package kz.pompei.oneGwtStands.client.simpleadapters;

import static kz.pompei.OneGwt.ifaces.util.StrUtil.killPackage;

import java.util.ArrayList;
import java.util.List;

import kz.pompei.OneGwt.ifaces.util.Handler;
import kz.pompei.OneGwt.ifaces.util.HandlerKiller;
import kz.pompei.OneGwt.ifaces.widget.ButtonWidget;
import kz.pompei.OneGwt.ifaces.widget.ListWidget;
import kz.pompei.OneGwt.ifaces.widget.StateMessage;
import kz.pompei.OneGwt.ifaces.widget.TextWidget;
import kz.pompei.OneGwt.ifaces.widget.gwtadapters.Button_impl_ButtonWidget;
import kz.pompei.OneGwt.ifaces.widget.gwtadapters.ListBox_impl_ListWidget;
import kz.pompei.OneGwt.ifaces.widget.gwtadapters.TextBoxBase_impl_TextWidget;
import kz.pompei.oneGwtStands.client.stand.Stand;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.CssResource.NotStrict;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class SimpleAdaptersStandEP implements EntryPoint {
  
  private static final String LINE_STYLE = "stand-line";
  private static final String WALL_STYLE = "stand-wall";
  private static final String KEY_STYLE = "stand-keyElement";
  private static final String VALUE_STYLE = "stand-valueElement";
  
  public interface Resource extends ClientBundle {
    Resource INSTANCE = GWT.create( Resource.class );
    
    @NotStrict
    CssResource SimpleAdaptersStandEP();
    
  }
  
  @Override
  public void onModuleLoad() {
    Resource.INSTANCE.SimpleAdaptersStandEP().ensureInjected();
    
    Stand stand = new Stand();
    
    {
      VerticalPanel wall = new VerticalPanel();
      wall.addStyleName( WALL_STYLE );
      
      defineStandFor_TextBoxBase_impl_TextWidget( wall, stand );
      defineStandFor_Button_impl_ButtonWidget( wall, stand );
      defineStandFor_ListBox_impl_ListWidget1( wall, stand );
      defineStandFor_ListBox_impl_ListWidget2( wall, stand );
      
      stand.setSource( wall );
    }
    
    stand.run();
  }
  
  private void defineStandFor_TextBoxBase_impl_TextWidget(VerticalPanel wall, final Stand stand) {
    TextBox textBox = new TextBox();
    textBox.addStyleName( VALUE_STYLE );
    textBox.setText( "Начальный текст" );
    
    String prefix = killPackage( TextBoxBase_impl_TextWidget.class.getName() );
    
    HorizontalPanel line = new HorizontalPanel();
    line.addStyleName( LINE_STYLE );
    
    Label label = new Label( prefix + ": " );
    label.addStyleName( KEY_STYLE );
    line.add( label );
    line.add( textBox );
    
    wall.add( line );
    
    final TextWidget textWidget = new TextBoxBase_impl_TextWidget( textBox );
    
    final HandlerKiller handlerKiller = textWidget.addChangeHandler( new Handler() {
      @Override
      public void handle() {
        stand.log( "Value changed to: " + textWidget.get() );
      }
    } );
    
    stand.injectMenuItem( prefix + "->killChangeHandler", new Handler() {
      @Override
      public void handle() {
        handlerKiller.killHandler();
      }
    } );
    
    {
      final String str = "Начинается новый день";
      stand.injectMenuItem( prefix + "->set = " + str, new Handler() {
        @Override
        public void handle() {
          textWidget.set( str );
        }
      } );
    }
    stand.injectMenuItem( prefix + "->get", new Handler() {
      @Override
      public void handle() {
        Window.alert( textWidget.get() );
      }
    } );
    
    stand.injectStandart( prefix, textWidget );
  }
  
  private void defineStandFor_Button_impl_ButtonWidget(VerticalPanel wall, final Stand stand) {
    Button but = new Button();
    but.addStyleName( VALUE_STYLE );
    but.setText( "Нажми меня" );
    
    String prefix = killPackage( Button_impl_ButtonWidget.class.getName() );
    
    HorizontalPanel line = new HorizontalPanel();
    line.addStyleName( LINE_STYLE );
    
    Label label = new Label( prefix + ": " );
    label.addStyleName( KEY_STYLE );
    line.add( label );
    line.add( but );
    
    wall.add( line );
    
    final ButtonWidget buttonWidget = new Button_impl_ButtonWidget( but );
    
    final HandlerKiller handlerKiller = buttonWidget.addClickHandler( new Handler() {
      @Override
      public void handle() {
        stand.log( "Clicked button" );
      }
    } );
    
    stand.injectMenuItem( prefix + "->killChangeHandler", new Handler() {
      @Override
      public void handle() {
        handlerKiller.killHandler();
      }
    } );
    
    stand.injectStandart( prefix, buttonWidget );
  }
  
  private void defineStandFor_ListBox_impl_ListWidget1(VerticalPanel wall, Stand stand) {
    ListBox box = new ListBox( false );
    box.addStyleName( VALUE_STYLE );
    box.setWidth( "20em" );
    
    String prefix = killPackage( ListBox_impl_ListWidget.class.getName() ) + "1";
    
    HorizontalPanel line = new HorizontalPanel();
    line.addStyleName( LINE_STYLE );
    
    Label label = new Label( prefix + ": " );
    label.addStyleName( KEY_STYLE );
    line.add( label );
    line.add( box );
    
    wall.add( line );
    
    final ListWidget<TestRecord> listWidget = new TestRecordList( box );
    
    injectMenus( stand, prefix, listWidget );
  }
  
  private void defineStandFor_ListBox_impl_ListWidget2(VerticalPanel wall, Stand stand) {
    ListBox box = new ListBox( false );
    box.addStyleName( VALUE_STYLE );
    box.setWidth( "20em" );
    box.setVisibleItemCount( 13 );
    
    String prefix = killPackage( ListBox_impl_ListWidget.class.getName() ) + "2";
    
    HorizontalPanel line = new HorizontalPanel();
    line.addStyleName( LINE_STYLE );
    
    Label label = new Label( prefix + ": " );
    label.addStyleName( KEY_STYLE );
    line.add( label );
    line.add( box );
    
    wall.add( line );
    
    final ListWidget<TestRecord> listWidget = new TestRecordList( box );
    
    injectMenus( stand, prefix, listWidget );
  }
  
  private void injectMenus(Stand stand, String prefix, final ListWidget<TestRecord> listWidget) {
    stand.injectStandart( prefix, listWidget );
    
    int counts[] = new int[] { 10, 20, 50, 100, 1000, 10000 };
    for (int count : counts) {
      final int finalCount = count;
      stand.injectMenuItem( prefix + "->set records->" + count, new Handler() {
        @Override
        public void handle() {
          listWidget.set( createTestRecords( finalCount ) );
        }
      } );
    }
    stand.injectMenuItem( prefix + "->clean", new Handler() {
      @Override
      public void handle() {
        listWidget.clean();
      }
    } );
    stand.injectMenuItem( prefix + "->addOrUpdate A13", new Handler() {
      @Override
      public void handle() {
        listWidget.addOrUpdate( new TestRecord( "A13", "Сансэй", 113 ) );
      }
    } );
    
    String ids[] = new String[] { null, "A13", "A0", "A3", "A70", "left" };
    for (final String id : ids) {
      stand.injectMenuItem( prefix + "->select->" + id, new Handler() {
        @Override
        public void handle() {
          listWidget.select( id );
        }
      } );
      stand.injectMenuItem( prefix + "->scrollToView->" + id, new Handler() {
        @Override
        public void handle() {
          listWidget.scrollToView( id );
        }
      } );
    }
    
    for (final StateMessage stateMessage : StateMessage.values()) {
      stand.injectMenuItem( prefix + "->setStateMessage->" + stateMessage.name(), new Handler() {
        @Override
        public void handle() {
          listWidget.setStateMessage( stateMessage );
        }
      } );
    }
    
  }
  
  private List<TestRecord> createTestRecords(int count) {
    List<TestRecord> ret = new ArrayList<TestRecord>();
    for (int i = 0; i < count; i++) {
      String id = "A" + i;
      ret.add( new TestRecord( id, "Иванов " + (i + 1) + "-й", (i * 9) % 70 + 1 ) );
    }
    return ret;
  }
}
